package com.woniuxy.meal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.meal.common.RedisKey;
import com.woniuxy.meal.dao.CommentAttachmentMapper;
import com.woniuxy.meal.dao.DietOrderFoodMapper;
import com.woniuxy.meal.entity.*;
import com.woniuxy.meal.dao.CommentInfoMapper;
import com.woniuxy.meal.exception.CommentException.CommentException;
import com.woniuxy.meal.exception.CommentException.CommentExceptionCode;
import com.woniuxy.meal.exception.orderException.OrderException;
import com.woniuxy.meal.exception.orderException.OrderExceptionCode;
import com.woniuxy.meal.exception.storeInfoException.StoreInfoException;
import com.woniuxy.meal.exception.storeInfoException.StoreInfoExceptionCode;
import com.woniuxy.meal.form.AddCommentForm;
import com.woniuxy.meal.form.SearchCommentForm;
import com.woniuxy.meal.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.meal.service.dto.CommentInfoDto;
import com.woniuxy.meal.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 评价信息表 服务实现类
 * </p>
 *
 * @author zz
 * @since 2023年06月12日
 */
@Service
public class CommentInfoServiceImpl extends ServiceImpl<CommentInfoMapper, CommentInfo> implements CommentInfoService {

    @Autowired
    private StoreInfoService storeInfoService;
    @Autowired
    private DietOrderService orderService;
    @Autowired
    private UserService userService;
    @Autowired
    private CommentInfoMapper mapper;
    @Autowired
    private CommentAttachmentMapper commentAttachmentMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private DietOrderFoodMapper orderFoodMapper;
    @Override
    @Transactional
    public CommentInfo add(AddCommentForm form, Long id) throws Exception {
        StoreInfo storeInfo = storeInfoService.getById(form.getStoreId());//订单界面需要storeId
        if(storeInfo==null ||storeInfo.getDeleteFlag()==1){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_IS_NOT_EXIST);
        }
        DietOrder order = orderService.getById(form.getOrderNum());
        if(order==null ||order.getState()!=3){
            throw new CommentException(CommentExceptionCode.COMMENT_NOT_ACCESS);
        }
        if(order.getUserId()!=id){
            throw new CommentException(CommentExceptionCode.COMMENT_NOT_ACCESS);
        }
        //修改order评论状态
        order.setEvaluate(1);
        orderService.saveOrUpdate(order);
        //修改商家评价时间
        storeInfo.setEvaluateDate(LocalDate.now());
        //修改comment数据库
        CommentInfo commentInfo = BeanUtil.toBean(form, CommentInfo.class);
        User user = userService.getById(id);
        commentInfo.setUserPhoto(user.getUserImg());
        commentInfo.setUserName(user.getUserName());
        commentInfo.setDate(LocalDateTime.now());
        commentInfo.setUserId(id);
        commentInfo.setDeleteFlag(0);
        commentInfo.setReplayFlag(0);
        mapper.insert(commentInfo);
        //增加附件表
        if(form.getFilePath()!=null){
            CommentAttachment commentAttachment = new CommentAttachment();
            commentAttachment.setFilePath(form.getFilePath());
            commentAttachment.setCommentId(commentInfo.getId());
            commentAttachmentMapper.insert(commentAttachment);
        }
        //修改商家评分redis
        if(form.getDishesScore()!=null || form.getStoreScore()!=null || form.getDphScore()!=null){
            if(redisUtil.exist(RedisKey.getCommentCount(storeInfo.getId()))){
                String commentCount = redisUtil.getString(RedisKey.getCommentCount(storeInfo.getId()));
                int oldCount = Integer.parseInt(commentCount);
                redisUtil.delete(RedisKey.getCommentCount(storeInfo.getId()));
                redisUtil.setString(RedisKey.getCommentCount(storeInfo.getId()),(oldCount+1)+"");

            }else{

                redisUtil.setString(RedisKey.getCommentCount(storeInfo.getId()),"1");
            }


            if(redisUtil.exist(RedisKey.getDphResultScore(storeInfo.getId()))){
                String dphScore = redisUtil.getString(RedisKey.getDphResultScore(storeInfo.getId()));//过去的平均评分
                String oldCount = redisUtil.getString(RedisKey.getCommentCount(storeInfo.getId())); //评价总数
                int dphOldScore = Integer.parseInt(dphScore);
                int oldTime = Integer.parseInt(oldCount);
                int newScore =(dphOldScore+form.getDishesScore())/(oldTime+1);
                redisUtil.delete(RedisKey.getDphResultScore(storeInfo.getId()));
                redisUtil.setString(RedisKey.getDphResultScore(storeInfo.getId()),newScore+"");
                storeInfo.setDphScore(Double.valueOf(newScore));
            }else{
                redisUtil.setString(RedisKey.getDphResultScore(storeInfo.getId()),form.getDphScore()+"");
                storeInfo.setDphScore(Double.valueOf(form.getDphScore()));
            }

            if(redisUtil.exist(RedisKey.getStoreResultScore(storeInfo.getId()))){
                String dphScore = redisUtil.getString(RedisKey.getStoreResultScore(storeInfo.getId()));//过去的平均评分
                String oldCount = redisUtil.getString(RedisKey.getCommentCount(storeInfo.getId())); //评价总数
                int dphOldScore = Integer.parseInt(dphScore);
                int oldTime = Integer.parseInt(oldCount);
                int newScore =(dphOldScore+form.getDishesScore())/(oldTime+1);
                redisUtil.delete(RedisKey.getStoreResultScore(storeInfo.getId()));
                redisUtil.setString(RedisKey.getStoreResultScore(storeInfo.getId()),newScore+"");
                storeInfo.setStoreScore(Double.valueOf(newScore));
            }else{
                redisUtil.setString(RedisKey.getStoreResultScore(storeInfo.getId()),form.getDphScore()+"");
                storeInfo.setStoreScore(Double.valueOf(form.getStoreScore()));
            }

            if(redisUtil.exist(RedisKey.getFoodResultScore(storeInfo.getId()))){
                String dphScore = redisUtil.getString(RedisKey.getFoodResultScore(storeInfo.getId()));//过去的平均评分
                String oldCount = redisUtil.getString(RedisKey.getCommentCount(storeInfo.getId())); //评价总数
                int dphOldScore = Integer.parseInt(dphScore);
                int oldTime = Integer.parseInt(oldCount);
                int newScore =(dphOldScore+form.getDishesScore())/(oldTime+1);
                redisUtil.delete(RedisKey.getFoodResultScore(storeInfo.getId()));
                redisUtil.setString(RedisKey.getFoodResultScore(storeInfo.getId()),newScore+"");
                storeInfo.setDishesScore(Double.valueOf(form.getDishesScore()));
            }else{
                redisUtil.setString(RedisKey.getFoodResultScore(storeInfo.getId()),form.getDphScore()+"");
                storeInfo.setDishesScore(Double.valueOf(form.getDishesScore()));
            }
        }
        storeInfoService.saveOrUpdate(storeInfo);
        return commentInfo;
    }

    @Override
    public void del(Long commentId, Long id) {
        CommentInfo commentInfo = this.getById(commentId);
        if(commentInfo==null ||commentInfo.getDeleteFlag()==1){
            throw new CommentException(CommentExceptionCode.COMMENT_NOT_EXIST);
        }
        if(commentInfo.getUserId()!=id){
            throw new CommentException(CommentExceptionCode.USER_NOT_ACCESS_DEL);
        }
        commentInfo.setDeleteFlag(1);
        this.saveOrUpdate(commentInfo);
    }

    @Override
    public List<CommentInfoDto> getComment(SearchCommentForm form) {
        QueryWrapper<CommentInfo> queryWrapper = new QueryWrapper<>();
        StoreInfo storeInfo = storeInfoService.getById(form.getStoreId());
        if(form.getStoreId()!=null){ //该商铺所有评价
            if(storeInfo==null){
                throw new StoreInfoException(StoreInfoExceptionCode.STORE_IS_NOT_EXIST);
            }
            queryWrapper.eq("storeId",form.getStoreId()).eq("deleteFlag",0);

        }
        if(form.getOrderNum()!=null){
            DietOrder order = orderService.getById(form.getOrderNum());
            if(order==null){
                throw new OrderException(OrderExceptionCode.ORDER_NOT_EXIST);
            }
            queryWrapper.eq("orderNum",form.getOrderNum());
        }
        List<CommentInfo> commentInfos = mapper.selectList(queryWrapper);
        ArrayList<CommentInfoDto> dtos = new ArrayList<>();
        for (CommentInfo commentInfo : commentInfos) {
            CommentInfoDto dto = BeanUtil.toBean(commentInfo, CommentInfoDto.class);
            dto.setStoreName(storeInfo.getStoreName());
            dto.setLogo(storeInfo.getLogo());
            Integer result =(commentInfo.getStoreScore()+commentInfo.getDishesScore()+commentInfo.getDphScore())/3;
            dto.setResultScore(result);
            ArrayList<String> urls = new ArrayList<>();
            List<CommentAttachment> commentAttachments = commentAttachmentMapper.selectList(new QueryWrapper<CommentAttachment>());
            for (CommentAttachment commentAttachment : commentAttachments) {
                urls.add(commentAttachment.getFilePath());
            }
            dto.setUrls(urls);
            dtos.add(dto);
        }
        return dtos;
    }
}
